Part One: The Scene Graph


Part Two: The VRML Source Code (buzz.wrl)

Here is the entire VRML 2.0 source code. Type (or paste) this code into a file called "buzz.wrl".

#VRML V2.0 utf8

#set camera position
Viewpoint {
   position 0 0 3
}

#generate time events
DEF BUZZGLASS TimeSensor {
  loop TRUE
  enabled TRUE
  cycleInterval 0.1
  stopTime -1
}

#the ball to be animated
DEF BUZZ Transform {
  children [
    Shape {
      appearance Appearance {
        material DEF BUZZMAT Material {}
      }
      geometry Sphere { radius 0.1 }
    }
  ]
}

DEF BUZZSCRIPT Script{
  url "buzz.class"
  scriptType "javabc"
  eventIn SFTime move
  eventOut SFVec3f buzztrans
}

ROUTE BUZZGLASS.cycleTime TO BUZZSCRIPT.move
ROUTE BUZZSCRIPT.buzztrans TO BUZZ.set_translation

Part Three: The Java Source Code (buzz.java)

Here is the Java source code. Type this into a file called "buzz.java".

import vrml.*;
import vs.*;

public class buzz extends Script {

   //Connect buzzpos to the translation the ball
   SFVec3f buzzpos = (SFVec3f)getEventOut("buzztrans");

   //Number of steps before we change direction again
   final int numSteps = 10;
   //Current step in the animation
   int currStep = 0;
   //Unit direction vector
   float [] direction = new float [3];
   //New position to move to in current step
   float [] newPos = new float [3];
   //Starting position in this 10-step phase
   float [] currPos = new float [3];
   //Interpolation fraction
   float inc = 1.0f/(float)numSteps; 
   float perc = 0;

   public buzz() {
     int i;
   
     for(i = 0; i < 3; i++) {
       currPos[i] = 0;
       direction[i] = (float)Math.random();        
     }
     float l = (float)Math.sqrt( 
                          (direction[0]*direction[0]) +
                          (direction[1]*direction[1]) +
                          (direction[2]*direction[2]) );
     for(i = 0; i < 3; i++) {
        direction[i] /= l;        
     }
   }

   public void move(ConstSFTime ev, ConstSFTime time) {
     int i; 

     //New Phase
     if(currStep == 0) { 
       for(i = 0; i < 3; i++) {
          currPos[i] = direction[i];
          direction[i] = (float)Math.random();        
       }
       float l = (float)Math.sqrt( (direction[0]*direction[0]) +
                            (direction[1]*direction[1]) +
                            (direction[2]*direction[2]) );
       for(i = 0; i < 3; i++) {
          direction[i] /= l;        
       }
       perc = 0;
     }   

     //Update postion
     for(i = 0; i < 3; i++) {
        newPos[i] = (perc * direction[i]) + ( (1.0f-perc) * currPos[i]) ;
     }
     perc += inc;
     buzzpos.setValue(newPos);
     currStep++;

     //End of a phase
     if (currStep == numSteps) {
        currStep = 0;
     }
   }
}